<?php
require_once 'St/Db/Table.php';
class BatteryModel extends St_Db_Table {
	
	/*
	 * save data after parse
	 */
	protected $_data = null;
	/*
	 * save data after calculate
	 */
	protected $_resultData = null;
	/*
	 * table name
	 */
	protected $_name = "battery_data";
	/*
	 * save current battery
	 */
	protected $_battery = null;
	/*
	 * save string from client
	 */
	
	protected $_dataString = "";
	
	/*
    	    100			MessageID	3
			2010			Year		4
			10			Month		2
			25			Date		2
			111623			Time		6
			10BAB0F501080051	BatteryiD	16
			2400CE3630		RFID		10
			000117			Voltage1	6
			000000			Voltage2	6
			000000			Voltage3	6
			000000			Voltage4	6
			0000000000		Current In	10	
			0000000412		Current Out	10
			00004083		Temp		8
    	 */
	
	public $dataFormat = array(
				    		"MessageID"     => 3,
				    		"Year"          => 4,
				    		"Month"         => 2,
				    		"Date"          => 2,
				    		"Time"          => 6,
				    		"BatteryID"     => 16,
				    		"RFIDTag"       => 10,
				    		"Voltage1"      => 6,
				    		"Voltage2"      => 6,
				    		"Voltage3"      => 6,
				    		"Voltage4"      => 6,
				    		"CurrentIn"     => 10,
				    		"CurrentOut"    => 10,
				    		"Temperature"   => 6
				    	);

	public $errorMsg = "";		

	private $_totalFormat = 0;
				    	
	public function __construct($dataString = ""){
		parent::__construct();
		/*
			$testCase = array("00AA" => 85, "0032" => 25, "0001" => 0.5, "0000" => 0, "FFFF" => -0.5, "FFCE" => -25, "FF92" => -55);
			foreach($testCase as $k => $v) {
				echo "{$k} => " . $this->convertTemperature($k) . " ({$v})<br />";
			}
		*/
		$total = 0;
		foreach($this->dataFormat as $key => $v) {
				$total += $v;
		}
		$this->_totalFormat = $total;
		
		$this->_dataString = $dataString;
		if($this->_dataString != "") {
			$data = $this->parseData($this->_dataString);
			$this->_battery = $this->_db->fetchRow($this->getAdapter()->quoteInto("SELECT * FROM battery_list WHERE BatteryID = ?", $data['BatteryID']));
		}               

	}
	
	public function parseData($dataString = false) {
		
		if($dataString) {
			$this->_dataString = $dataString;
		}
		
		//check exist data
    	if(!$this->_dataString){
    		die("Data not found");
    	}
    	
    	//check number of letter
    	if(strlen($this->_dataString) != $this->_totalFormat) {
    		die("String is not right format");
    	}
    	
		$start = 0;
    	foreach($this->dataFormat as $key => $value) {
    		$this->_data[$key] = substr($this->_dataString, $start, $value);
    		$start += $value;
    	}
//    	echo "<pre>";print_r($this->_data);die;
    	return $this->_data;
	}
	
	public function processData($dataString = "")
	{
		if ($dataString != "") {
			$this->parseData($dataString);
		}
		
		if($this->_battery == null){
			$this->_battery = $this->_db->fetchRow($this->getAdapter()->quoteInto("SELECT * FROM battery_list WHERE BatteryID = ?", $this->_data['BatteryID']));
			if(!$this->_battery){
				die("Battery not found");
			}
		}
		
		
		
		$data = array();
		$battery = (array)$this->_battery;
		//echo "<pre>";print_r($battery);die;
		$data['MessageID'] = $this->_data['MessageID'];
		$data['BatteryID'] = $this->_data['BatteryID'];
		$data['RFIDTag'] = $this->_data['RFIDTag'];
		$data['Voltage1'] = $this->_data['Voltage1'] * (5/1023) * $battery['VoltageKFactor'];
		$data['Voltage2'] = $this->_data['Voltage2'] * (5/1023) * $battery['VoltageKFactor'];
		$data['Voltage3'] = $this->_data['Voltage3'] * (5/1023) * $battery['VoltageKFactor'];
		$data['Voltage4'] = $this->_data['Voltage4'] * (5/1023) * $battery['VoltageKFactor'];
		$data['Temperature'] = $this->convertTemperature($this->_data['Temperature']);
		$data['DateTime'] = mktime(substr($this->_data['Time'],0,2),substr($this->_data['Time'],2,2),substr($this->_data['Time'],4,2), $this->_data['Month'],$this->_data['Date'],$this->_data['Year']);
		
		$lastTime = $this->getLastUpdateTime($this->_data['BatteryID']);
		$distanceTime = 1;
		if($lastTime) {
			$distanceTime = $data['DateTime'] - $lastTime;
			if($distanceTime == 0){
				$distanceTime = 1;
			}
		}
		
		if(intval($this->_data['CurrentIn']) != 0){
			$data['CurrentIn'] = ($this->_data['CurrentIn'] - $battery['CurrentKFactor']) * $battery['CurrentMultiplyFactor'];
			if($data['CurrentIn'] < 0) {
				$data['CurrentIn'] = 0;
			} else {
				$data['CurrentIn'] = $data['CurrentIn']/10/$distanceTime;
			}
		} else {
			$data['CurrentIn'] = 0;
		}
		 
		if(intval($this->_data['CurrentOut']) != 0){
			$data['CurrentOut'] = ($battery['CurrentKFactor'] - $this->_data['CurrentOut']) * $battery['CurrentMultiplyFactor'];
			if($data['CurrentOut'] < 0) {
				$data['CurrentOut'] = 0;
			} else {
				$data['CurrentOut'] = $data['CurrentOut']/10/$distanceTime;
			}
		} else {
			$data['CurrentOut'] = 0;
		}
		
		$this->_resultData = $data;
		$batteryDataId = $this->insert($this->_resultData);
		
		$batteryConfig = St_Registry::getConfig("battery"); 
		
		if($batteryConfig['saveRawData']) {
			$this->_data['BatteryDataID'] = $batteryDataId;
			$this->processRawData($this->_data);
		}
		
		return $batteryDataId;
	}
	
	public function processArrayData($newData)
	{
		if($this->_battery == null){
			$this->_battery = $this->_db->fetchRow($this->getAdapter()->quoteInto("SELECT * FROM battery_list WHERE BatteryID = ?", $newData['BatteryID']));
			if(!$this->_battery){
				$this->errorMsg = "Battery not found";
				return false;
			}
		}
		$this->_data = $newData;
		$data = array();
		$battery = (array)$this->_battery;
		$data['MessageID'] = $this->_data['MessageID'];
		$data['BatteryID'] = $this->_data['BatteryID'];
		$data['RFIDTag'] = $this->_data['RFIDTag'];
		$data['Voltage1'] = $this->_data['Voltage1'] * (5/1023) * $battery['VoltageKFactor'];
		$data['Voltage2'] = $this->_data['Voltage2'] * (5/1023) * $battery['VoltageKFactor'];
		$data['Voltage3'] = $this->_data['Voltage3'] * (5/1023) * $battery['VoltageKFactor'];
		$data['Voltage4'] = $this->_data['Voltage4'] * (5/1023) * $battery['VoltageKFactor'];
		$data['Temperature'] = $this->convertTemperature($this->_data['Temperature']);
		$data['DateTime'] = mktime($this->_data['Time']['hour'],$this->_data['Time']['minute'],$this->_data['Time']['second'], $this->_data['Month'],$this->_data['Date'],$this->_data['Year']);
		
		$lastTime = $this->getLastUpdateTime($this->_data['BatteryID']);
		$distanceTime = 1;
		if($lastTime) {
			$distanceTime = $data['DateTime'] - $lastTime;
			if($distanceTime == 0){
				$distanceTime = 1;
			}
		}
		
		if(intval($this->_data['CurrentIn']) != 0){
			$data['CurrentIn'] = ($this->_data['CurrentIn'] - $battery['CurrentKFactor']) * $battery['CurrentMultiplyFactor'];
			if($data['CurrentIn'] < 0) {
				$data['CurrentIn'] = 0;
			} else {
				$data['CurrentIn'] = $data['CurrentIn']/10/$distanceTime;
			}
		} else {
			$data['CurrentIn'] = 0;
		}
		 
		if(intval($this->_data['CurrentOut']) != 0){
			$data['CurrentOut'] = ($battery['CurrentKFactor'] - $this->_data['CurrentOut']) * $battery['CurrentMultiplyFactor'];
			if($data['CurrentOut'] < 0) {
				$data['CurrentOut'] = 0;
			} else {
				$data['CurrentOut'] = $data['CurrentOut']/10/$distanceTime;
			}
		} else {
			$data['CurrentOut'] = 0;
		}
		
		$this->_resultData = $data;
		return $this->insert($this->_resultData);
	}
	
	public function getLastUpdateTime($batteryId)
	{		
		$sql = "SELECT DateTime FROM battery_data WHERE BatteryID = '{$batteryId}' ORDER BY DateTime DESC LIMIT 0,1";
		return $this->_db->fetchOne($sql);
	}
	
	public function convertTemperature($input)
	{	
		$sign = 1;
		$result = hexdec($input);
		if($result > hexdec("FF")) {
			$sign = -1;
			$bin = $this->hex2bin($input);
			$binrev = $this->revbit($bin);
			$result = bindec($binrev) + 1;
		}
		
		$result *= $sign;
		$result /= 2;
		return $result;
	}
	
	public function hex2bin($str) {
	    return decbin(hexdec($str));
	}
	
	public function revbit($binStr)
	{
		$str = $binStr . "";
		$str = str_replace("0","k",$str);
		$str = str_replace("1","0",$str);
		$str = str_replace("k","1",$str);
		return $str;
	}
	
	public function processRawData($data)
	{
		require_once 'BatteryRawDataModel.php';
		$rawDataObj = new BatteryRawDataModel();
		
		$record = array();
		
		$record['BatteryDataID'] = @$data['BatteryDataID'];
		$record['DateTime'] = $data['Date'] . "-" . $data['Month'] . "-" . $data['Year'] . " " . $data['Time'];
		$record['Voltage1'] = @$data['Voltage1'];
		$record['Voltage2'] = @$data['Voltage2'];
		$record['Voltage3'] = @$data['Voltage3'];
		$record['Voltage4'] = @$data['Voltage4'];
		$record['CurrentIn'] = @$data['CurrentIn'];
		$record['CurrentOut'] = @$data['CurrentOut'];
		$record['Temperature'] = @$data['Temperature'];
		return $rawDataObj->insert($record);
		
	}
	
	public function getLastId($filter = false)
	{
		
		$select = $this->_db->select (array("BatteryDataID"))->from ( 'battery_data' )->order('BatteryDataID DESC');
		
		if($filter) {
			if($filter['BatteryID'] != "*"){
				$select->where($this->_db->quoteInto("BatteryID = ?", $filter['BatteryID']));	
			}
		}
		$select->limit(1);
		return $this->_db->fetchOne($select);
	}
	
}